package com.geese.module.user.service;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.geese.common.entity.Business;
import com.geese.exception.BusinessException;
import com.geese.module.business.dao.BusinessMapper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.geese.common.constants.BusinessConstants;
import com.geese.common.entity.Account;
import com.geese.common.entity.Courier;
import com.geese.common.entity.Permission;
import com.geese.common.entity.Role;
import com.geese.common.entity.User;
import com.geese.common.util.JSONUtil;
import com.geese.common.util.MD5Util;
import com.geese.module.ceo.dao.CourierMapper;
import com.geese.module.security.dao.RoleMapper;
import com.geese.module.security.service.PermissionService;
import com.geese.module.security.service.RoleService;
import com.geese.module.user.dao.AccountMapper;
import com.geese.module.user.dao.UserMapper;
import com.geese.module.user.model.SecurityUser;
import com.geese.util.CommonUtil;
import com.geese.util.UserCacheUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Sets;

/**
 * 用户
 */
@Service
public class UserService {

    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CourierMapper courierMapper;
	@Autowired
	private BusinessMapper businessMapper;
	@Autowired
	private RoleService roleService;
	@Autowired
	private PermissionService permissionService;
    
//    private static final int LOGIN_TIMEOUT_SEC = 3600;
//    private Cache<String, SecurityUser> loginUsers ;
//    private Set<String> businessLoginIds = Sets.newHashSet();
    
    public UserService() {
//    	loginUsers = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(LOGIN_TIMEOUT_SEC, TimeUnit.SECONDS)
//				.build();
    	
    }

    /**
     * CEO登录
     */
    public ImmutableMap ceoLogin(String account, String pwd) {
    	Account accountDO = accountMapper.findByAccount(account);
    	if(accountDO == null) {
    		throw new BusinessException(120001);
    	}
    	if(!Objects.equals(encodePwd(pwd), accountDO.getPassword())) {
    		throw new BusinessException(120001);
    	}
    	if(Objects.equals(accountDO.getBlock(), 1)) {
    		throw new BusinessException(120002);
    	}
    	User user = userMapper.findById(accountDO.getUserId());
    	if(!Objects.equals(user.getUserType(), BusinessConstants.CEO_TYPE)) {
    		throw new BusinessException(120001);
    	}
    	Courier ceo = courierMapper.findByUserId(accountDO.getUserId());
    	String extra = JSONUtil.objectToJson(ceo);
    	String token = RandomStringUtils.randomAlphabetic(32);
    	UserCacheUtil.addLoginUser(token, new SecurityUser(accountDO, user, extra));
    	return ImmutableMap.of("token", token, "ceo", ceo);
    }
    
    /**
     * 超级管理员登录
     */
    public ImmutableMap<String, Object> adminLogin(String account, String pwd) {
    	Account accountDO = accountMapper.findByAccount(account);
    	if(accountDO == null) {
    		throw new BusinessException(120001);
    	}
    	if(!Objects.equals(encodePwd(pwd), accountDO.getPassword())) {
    		throw new BusinessException(120001);
    	}
    	if(Objects.equals(accountDO.getBlock(), 1)) {
    		throw new BusinessException(120002);
    	}
    	User user = userMapper.findById(accountDO.getUserId());
    	if(!Objects.equals(user.getUserType(), BusinessConstants.ADMIN_TYPE)) {
    		throw new BusinessException(120001);
    	}
    	String token = RandomStringUtils.randomAlphabetic(32);
    	UserCacheUtil.addLoginUser(token, new SecurityUser(accountDO, user));
    	List<Role> roleList = roleService.listByUserId(accountDO.getUserId());
    	List<Permission> permissionList = permissionService.listByRoleIds(CommonUtil.getRoleIdSet(roleList));
    	List<Integer> idsList = Lists.newArrayListWithCapacity(permissionList.size());
    	for(Permission permission : permissionList) {
    		idsList.add(permission.getId());
    	}
    	return ImmutableMap.of("token", token, "permissionList", idsList);
    }

	/**
	 * 商家登录
	 */
	public String businessLogin(String account, String pwd) {
		Account accountDO = accountMapper.findByAccount(account);
		if(accountDO == null) {
			throw new BusinessException(120001);
		}
		if(!Objects.equals(encodePwd(pwd), accountDO.getPassword())) {
			throw new BusinessException(120001);
		}
		if(Objects.equals(accountDO.getBlock(), 1)) {
			throw new BusinessException(120002);
		}
		User user = userMapper.findById(accountDO.getUserId());
		if(!Objects.equals(user.getUserType(), BusinessConstants.BUSINESS_TYPE)) {
			throw new BusinessException(120001);
		}
		Business business = businessMapper.findByUserId(accountDO.getUserId());
		String extra = JSONUtil.objectToJson(business);
		String token = RandomStringUtils.randomAlphabetic(32);
		UserCacheUtil.addBusinessLoginUser(token, new SecurityUser(accountDO, user, extra));
		return token;
	}

	/**
	 * 小二登录
	 */
	public String courierLogin(String account, String pwd) {
		Account accountDO = accountMapper.findByAccount(account);
		if(accountDO == null) {
			throw new BusinessException(120001);
		}
		if(!Objects.equals(encodePwd(pwd), accountDO.getPassword())) {
			throw new BusinessException(120001);
		}
		if(Objects.equals(accountDO.getBlock(), 1)) {
			throw new BusinessException(120002);
		}
		User user = userMapper.findById(accountDO.getUserId());
		if(!Objects.equals(user.getUserType(), BusinessConstants.WAITER_TYPE)) {
			throw new BusinessException(120001);
		}
		Courier courier = courierMapper.findByUserId(accountDO.getUserId());
		String extra = JSONUtil.objectToJson(courier);
		String token = RandomStringUtils.randomAlphabetic(32);
		UserCacheUtil.addLoginUser(token, new SecurityUser(accountDO, user, extra));
		return token;
	}



    /**
     * 获取登录用户
     */
    public SecurityUser getLoginUser(String token) {
    	checkUser(token);
		return UserCacheUtil.getLoginUser(token);
	}
    
    /**
     * 获取登录用户
     */
    public SecurityUser getUser(String token) {
		return UserCacheUtil.getLoginUser(token);
	}
    
    /**
     * 修改密码
     */
	public void updatePwd(Integer userId, String oldPwd, String newPwd) {
		Account loginModel = accountMapper.findByUserId(userId);
		if(loginModel == null) {
			throw new BusinessException(120001);
		}
		if(loginModel.getBlock() == 1) {
			throw new BusinessException(120002);
		}
		
        if(!Objects.equals(encodePwd(oldPwd), loginModel.getPassword())){
            throw new BusinessException(120001);
        }
        
        accountMapper.updatePwd(loginModel.getUserId(), encodePwd(newPwd));
	}
	
	/**
	 *  是否登录
	 */
	public void checkUser(String token) {
		checkUser(token, false);
	}
	
	/**
	 *  是否登录
	 */
	private void checkUser(String token, boolean isBusiness) {
		if(StringUtils.isEmpty(token)) {
			throw new BusinessException(120003);
		} 
		SecurityUser user = UserCacheUtil.getLoginUser(token);
		if(user == null) {
			if(isBusiness) {
				UserCacheUtil.removeBusinessToken(token);
			}
			throw new BusinessException(120004);
		}
	}
	
	/**
	 * ceo是否登陆
	 */
	public void checkCeoUser(String token) {
		checkUser(token);
	}
	
	/**
	 * 商家是否登陆
	 */
	public void checkBusinessUser(String token) {
		boolean isLogin = UserCacheUtil.checkBusinessUser(token);
		if(!isLogin) {
//			throw new RuntimeException("User doesn't doLogin");
			throw new BusinessException(120004);
		}
		checkUser(token, true);
	}
	
	/**
	 * 退出登录
	 */
	public void logout(String token) {
		UserCacheUtil.logout(token);
	}
	
	private String encodePwd(String pwd) {
		if(StringUtils.isEmpty(pwd)) {
			return "";
		}
		return MD5Util.encrypt(pwd);
	}

}
